package com.linekong.mmo.navmesh;

import java.util.List;

public class RecastLib
{
	static
	{
		try
		{
			NativeLoad.loadNative("RecastLibrary");
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	public native int loadFromPath(String path, int maxNodes, float[] extents, float[] wideExtents);

	public native int loadFromData(byte[] meshData, int maxNodes, float[] extents, float[] wideExtents);

	public native List<float[]> findStraightPath(int navmeshId, float x1, float y1, float z1, float x2, float y2, float z2);

	public native float[] getPolyHeight(int navMeshId, float x1, float y1, float z1);

	public native float[] findNearestPoly(int navMeshId, float x, float y, float z, boolean useWideExtents);

	public native boolean raycast(int navMeshId, float x1, float y1, float z1, float x2, float y2, float z2);

	public native float[] moveAlongSurface(int navMeshId, float x1, float y1, float z1, float x2, float y2, float z2);

	public native int release(int navmeshId);

	private int mMaxNodes = 1024;
	private float[] mExtents = { 1.0f, 1.0f, 1.0f };
	private float[] mWideExtents = { 10.0f, 10.0f, 10.0f };

	private final float epsilon = 0.01f;

	public int loadFromPath(String path)
	{
		return loadFromPath(path, mMaxNodes, mExtents, mWideExtents);
	}

	public int loadFromData(byte[] meshData)
	{
		return loadFromData(meshData, mMaxNodes, mExtents, mWideExtents);
	}

	public boolean isPositionWalkable(int navMeshId, float x, float y, float z)
	{
		float[] resultPoint = findNearestPoly(navMeshId, x, y, z, false);
		if (resultPoint != null && resultPoint.length == 3)
		{
			float distance = calculateDistance(x, 0.0f, z, resultPoint[0], 0.0f, resultPoint[2]);
			if (distance < epsilon)
			{
				return true;
			}
		}

		return false;
	}

	private float calculateDistance(float x1, float y1, float z1, float x2, float y2, float z2)
	{
		float x = x1 - x2;
		float y = y1 - y2;
		float z = z1 - z2;
		double result = (double) (x * x + y * y + z * z);

		return (float) Math.sqrt(result);
	}
}
